package com.rabbit.videoplayer.widget.player

import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import com.rabbit.videoplayer.IMixPlayer
import com.rabbit.videoplayer.listener.player.OnCompletionListener
import com.rabbit.videoplayer.listener.player.OnErrorListener
import com.rabbit.videoplayer.listener.player.OnInfoListener
import com.rabbit.videoplayer.listener.player.OnLoadingStatusListener
import com.rabbit.videoplayer.listener.player.OnPreparedListener
import com.rabbit.videoplayer.listener.player.OnRenderingStartListener
import com.rabbit.videoplayer.listener.player.OnStateChangedListener
import com.rabbit.videoplayer.listener.player.OnVideoSizeChangedListener
import com.rabbit.videoplayer.response.PlayerType
import com.rabbit.videoplayer.tools.Constants
import com.rabbit.videoplayer.tools.VideoPlayerSPUtil
import com.tencent.rtmp.ITXVodPlayListener
import com.tencent.rtmp.TXLiveConstants
import com.tencent.rtmp.TXLiveConstants.PLAY_ERR_HLS_KEY
import com.tencent.rtmp.TXLiveConstants.PLAY_ERR_NET_DISCONNECT
import com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_BEGIN
import com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_END
import com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_LOADING
import com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_PROGRESS
import com.tencent.rtmp.TXLiveConstants.PLAY_EVT_VOD_LOADING_END
import com.tencent.rtmp.TXLiveConstants.PLAY_EVT_VOD_PLAY_PREPARED
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_ERR_DECODE_AUDIO_FAIL
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_ERR_DECODE_SUBTITLE_FAIL
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_ERR_DECODE_VIDEO_FAIL
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_ERR_PROCESS_VIDEO_FAIL
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_ERR_RENDER_FAIL
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_ERR_SYSTEM_PLAY_FAIL
import com.tencent.rtmp.TXVodConstants.VOD_PLAY_EVT_RCV_FIRST_I_FRAME
import com.tencent.rtmp.TXVodPlayConfig
import com.tencent.rtmp.TXVodPlayer
import com.tencent.rtmp.ui.TXCloudVideoView


class TXPlayerView(context: Context) : FrameLayout(context), IMixPlayer {

    private lateinit var vodPlayer: TXVodPlayer
    private lateinit var playerView: TXCloudVideoView

    private var currentPosition = 0
    private var bufferedPosition = 0
    private var isVodPrepared = false

    private var mOnPreparedListener: OnPreparedListener? = null
    private var mOnInfoListener: OnInfoListener? = null
    private var mOnLoadingStatusListener: OnLoadingStatusListener? = null
    private var mOnErrorListener: OnErrorListener? = null
    private var mOnCompletionListener: OnCompletionListener? = null
    private var mOnStateChangedListener: OnStateChangedListener? = null
    private var mOnRenderingStartListener: OnRenderingStartListener? = null
    private var mOnVideoSizeChangedListener: OnVideoSizeChangedListener? = null

    override fun initPlayer(context: Context): View {
        Log.e("mixPlayer", "腾讯播放器初始化...")
        vodPlayer = TXVodPlayer(context)
        playerView = TXCloudVideoView(context)
        val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        addView(playerView, layoutParams)
        // 绑定view
        vodPlayer.setPlayerView(playerView)
        // 禁止自动播放，之后调用resume来播放
        vodPlayer.setAutoPlay(false)
        // 允许硬件加速
        vodPlayer.enableHardwareDecode(VideoPlayerSPUtil.instance.isEnableHardDecoder)
        // 多码率自动切换index 参数传入-1
        vodPlayer.bitrateIndex = -1
        // 设置渲染缩放方式
        vodPlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN)

//        // 播放器全局缓存
//        // 在短视频播放场景中，视频文件的本地缓存是很刚需的一个特性，对于普通用户而言，一个已经看过的视频再次观看时，不应该再消耗一次流量。
//        // 格式支持：SDK 支持 HLS(m3u8) 和 MP4 两种常见点播格式的缓存功能。
//        // 开启时机：SDK 并不默认开启缓存功能，对于用户回看率不高的场景，也并不推荐您开启此功能。
//        // 开启方式：全局生效，在使用播放器开启。开启此功能需要配置两个参数：本地缓存目录及缓存大小。
//        val sdcardDir = context.getExternalFilesDir(null)
//        if (sdcardDir != null) {
//            //设置播放引擎的全局缓存目录
//            TXPlayerGlobalSetting.setCacheFolderPath(sdcardDir.path + "/txcache")
//            //设置播放引擎的全局缓存目录和缓存大小，//单位MB
////            TXPlayerGlobalSetting.setMaxCacheSize(500)
//        }
        vodPlayer.setVodListener(object : ITXVodPlayListener {
            override fun onPlayEvent(player: TXVodPlayer, event: Int, param: Bundle) {
                when(event){
                    PLAY_EVT_VOD_PLAY_PREPARED -> { // prepared
                        Log.e("TXPlayer", "PLAY_EVT_VOD_PLAY_PREPARED...." )
                        isVodPrepared = true
                        //开启终端极速高清
                        vodPlayer.setStringOption("PARAM_SUPER_RESOLUTION_TYPE", 1)
                        mOnPreparedListener?.onPrepared()
                    }

                    PLAY_EVT_PLAY_BEGIN -> { // 视频播放开始。
                        Log.e("TXPlayer", "PLAY_EVT_PLAY_BEGIN...." )

                    }

                    PLAY_EVT_PLAY_END -> {  // 视频播放结束。
                        Log.e("TXPlayer", "PLAY_EVT_PLAY_END...." )
                        speedValue = 1f
                        isVodPrepared = false

                        mOnCompletionListener?.onCompletion()
                    }
                    PLAY_EVT_PLAY_PROGRESS -> {
                        // 加载进度, 单位是毫秒
                        bufferedPosition = param.getInt(TXLiveConstants.EVT_PLAYABLE_DURATION_MS)
                        // 播放进度, 单位是毫秒
                        currentPosition = param.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS)
                        // 视频总长, 单位是毫秒
                        val durationMs = param.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS)
                        if (currentPosition > durationMs) {
                            currentPosition = 0
                        }
                        mOnInfoListener?.onInfo(Constants.INFO_CODE_CURRENT_POSITION, currentPosition.toLong())
                        mOnInfoListener?.onInfo(Constants.INFO_CODE_BUFFERED_POSITION, bufferedPosition.toLong())
                    }


                    PLAY_EVT_PLAY_LOADING -> {
                        // 显示当前网速
                        mOnLoadingStatusListener?.onLoadingBegin()
                    }
                    PLAY_EVT_VOD_LOADING_END -> {
                        // 对显示当前网速的 view 进行隐藏
                        mOnLoadingStatusListener?.onLoadingEnd()
                    }

                    VOD_PLAY_EVT_RCV_FIRST_I_FRAME -> {
                        mOnRenderingStartListener?.onRenderingStart()
                    }

                    // 出错事件
                    PLAY_ERR_NET_DISCONNECT, PLAY_ERR_HLS_KEY,VOD_PLAY_ERR_SYSTEM_PLAY_FAIL,VOD_PLAY_ERR_DECODE_VIDEO_FAIL,
                    VOD_PLAY_ERR_DECODE_AUDIO_FAIL,VOD_PLAY_ERR_DECODE_SUBTITLE_FAIL,VOD_PLAY_ERR_RENDER_FAIL,
                    VOD_PLAY_ERR_PROCESS_VIDEO_FAIL -> {
                        speedValue = 1f
                        // 播放出错
                        isVodPrepared = false
                        mOnErrorListener?.onError("$event")
                    }

                }

            }

            override fun onNetStatus(player: TXVodPlayer, bundle: Bundle) {
                //获取当前CPU使用率
//                val cpuUsage = bundle.getCharSequence(TXLiveConstants.NET_STATUS_CPU_USAGE)
//                //获取视频宽度
//                val videoWidth = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_WIDTH)
//                //获取视频高度
//                val videoHeight = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_HEIGHT)
//                //获取实时速率,  单位：kbps
//                val speed = bundle.getInt(TXLiveConstants.NET_STATUS_NET_SPEED)
//                //获取当前流媒体的视频帧率
//                val fps = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_FPS)
//                //获取当前流媒体的视频码率，单位 bps
//                val videoBitRate = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_BITRATE)
//                //获取当前流媒体的音频码率，单位 bps
//                val audioBitRate = bundle.getInt(TXLiveConstants.NET_STATUS_AUDIO_BITRATE)
//                //获取缓冲区（jitterbuffer）大小，缓冲区当前长度为0，说明离卡顿就不远了
//                val jitterbuffer = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_CACHE)
//                //获取连接的服务器的IP地址
//                val ip = bundle.getString(TXLiveConstants.NET_STATUS_SERVER_IP)

                // 获取实时速率, 单位：kbps
                val speed = bundle.getInt(TXLiveConstants.NET_STATUS_NET_SPEED)
                Log.d("播放器SDK", "TX播放器实时网速 -> $speed")
                //获取视频宽度
                val width = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_WIDTH)
                //获取视频高度
                val height = bundle.getInt(TXLiveConstants.NET_STATUS_VIDEO_HEIGHT)
                if (videoWidth != width || videoHeight != height) {
                    videoWidth = width
                    videoHeight = height
                    mOnVideoSizeChangedListener?.onVideoSizeChanged(videoWidth, videoHeight)
                }

            }
        })
        return this
    }

    private var videoWidth = 0
    private var videoHeight = 0

    override fun getDuration(): Long {
        return vodPlayer.duration.toLong() * 1000
    }

    override fun setAutoPlay(isAutoPlay: Boolean) {
        vodPlayer.setAutoPlay(isAutoPlay)
    }

    override fun getCurrentPosition(): Long {
        return currentPosition.toLong()
    }

    override fun getBufferedPosition(): Long {
        return bufferedPosition.toLong()
    }

    override fun getCurrentDownloadSpeed(): Long {
        return 0
    }

    override fun isPrepared(): Boolean {
        return isVodPrepared
    }

    override fun isPlaying(): Boolean {
        return vodPlayer.isPlaying
    }

    override fun seekTo(seek: Long) {
        vodPlayer.seek((seek / 1000).toInt())
    }

    override fun getSpeed(): Float {
        return speedValue
    }

    private var speedValue: Float = 1f
    override fun setSpeed(speed: Float) {
        this.speedValue = speed
        vodPlayer.setRate(speed)
    }

    override fun stop() {
        vodPlayer.stopPlay(true)
    }

    override fun pause() {
        vodPlayer.pause()
    }

    override fun start() {
        vodPlayer.resume()
    }

    override fun setLoop(isLoop: Boolean) {
        vodPlayer.isLoop = isLoop
    }

    override fun getLoop(): Boolean {
        return vodPlayer.isLoop
    }

    override fun setEnableHardDecoder(isEndableHardDecoder: Boolean) {
        // 允许硬件加速
        vodPlayer.enableHardwareDecode(isEndableHardDecoder)
    }

    private var renderMode = Constants.VIDEO_RESIZE_FILL
    override fun setScaleMode(model: Int) {
        renderMode = model
        when (model){
            Constants.VIDEO_RESIZE_FILL -> {
                vodPlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN)
            }
            else -> {
                vodPlayer.setRenderMode(TXLiveConstants.RENDER_MODE_ADJUST_RESOLUTION)
            }
        }

    }

    override fun getScaleMode(): Int {
        return renderMode
    }

    override fun setOnErrorListener(listener: OnErrorListener) {
        this.mOnErrorListener = listener
    }

    override fun setOnInfoListener(listener: OnInfoListener) {
        this.mOnInfoListener = listener
    }

    override fun setOnPreparedListener(listener: OnPreparedListener) {
        this.mOnPreparedListener = listener
    }

    override fun setOnCompletionListener(listener: OnCompletionListener) {
        this.mOnCompletionListener = listener
    }

    override fun setOnStateChangedListener(listener: OnStateChangedListener) {
        this.mOnStateChangedListener = listener
    }

    override fun setOnLoadingStatusListener(listener: OnLoadingStatusListener) {
        this.mOnLoadingStatusListener = listener
    }

    override fun setOnRenderingStartListener(listener: OnRenderingStartListener) {
        this.mOnRenderingStartListener = listener
    }

    override fun setOnVideoSizeChangedListener(listener: OnVideoSizeChangedListener) {
        this.mOnVideoSizeChangedListener = listener
    }


    private fun setPlayerConfig(header: Map<*, *>?) {
        val config = TXVodPlayConfig()
        // header
        if (header != null) {
            val headers: MutableMap<String, String> = HashMap()
            for ((key, value) in header) {
                if (key == null || value == null) continue
                val keyStr = key.toString()
                val valueStr = value.toString()
                if (TextUtils.isEmpty(keyStr) || TextUtils.isEmpty(valueStr)) continue
                headers[keyStr] = valueStr
            }
            config.headers = headers
        }
        config.isSmoothSwitchBitrate = true
        config.preferredResolution = 1920 * 1080
        // 设置是否精确 seek，默认 true
        config.isEnableAccurateSeek = true
        // 设置进度回调间隔，单位毫秒
        config.progressInterval = 1000
        // 最大预加载大小，单位 MB
        config.maxBufferSize = 20f
        config.timeout = 10
        config.connectRetryCount = 2
        vodPlayer.setConfig(config)
    }

    override fun onVodInit(vararg init: Any?): Boolean {
        // 处在播放状态，停止视频
        if (init.isEmpty() || init.size < 2) return false
        // 获取播放地址
        val url = init[0] as String
        // 设置起播时间
        val startPosition = init[1] as Long
        var headerMap: Map<*, *>? = null
        if (init.size >= 3) {
            headerMap = init[2] as Map<*, *>?
        }
        // 设置播放地址的header
        setPlayerConfig(headerMap)
        vodPlayer.setAutoPlay(false)  // 设置为非自动播放
        vodPlayer.setStartTime((startPosition / 1000).toFloat())
        // 设置播放器
        vodPlayer.startVodPlay(url)
        return false
    }

    override fun getPlayerType(): Int {
        return PlayerType.TX
    }

    override fun onVodPrepared(vararg prepared: Any) {

    }

    override fun onVodStart() {
        start()
    }

    override fun onVodFirstFrameStart() {

    }

    override fun onVodSwitchDisplayControlView() {

    }

    override fun onVodPause() {
        pause()
    }

    override fun onVodStop() {
        stop()
    }

    override fun onVodError(vararg params: Any) {

    }

    override fun onVodComplete() {

    }

    override fun onVodRelease() {
        stop()
        playerView.onDestroy()
    }

    override fun onVodLockedScreen(vararg params: Any) {

    }

    override fun onVodFullScreen(vararg params: Any) {

    }

    override fun onVodLoadingBegin() {

    }

    override fun onVodLoadingProgress(vararg params: Any) {

    }

    override fun onVodLoadingEnd() {

    }

    override fun onVodBackPress(): Boolean {
        return false
    }

    override fun onEpisodeSelected() {

    }

    override fun onVodShowUnlockUI(isDisplayUI: Boolean) {
        if (isDisplayUI && isPlaying()) {
            stop()
        }
    }

    override fun onVodSkits() {

    }

}